package game.core
{
	public class RxStateMachine
	{
		protected var m_states:Array;
		protected var m_state:RxState;
		protected var m_stateStack:Vector.<RxState>;
		protected var m_stateRequest:RxState;
		
		public function RxStateMachine()
		{
			this.m_states = new Array();
			this.m_stateStack = new Vector.<RxState>;
		}
		
		public function AddState(name:String, func:Function, disposable:Boolean) : void
		{
			var state:RxState = new RxState(name, func, disposable);
			this.m_states[name] = state;
		}
		
		public function GetState(name:String) : RxState
		{
			return this.m_states[name];
		}
		
		public function Update(deltaTime:Number) : RxState
		{
			if (this.m_stateRequest)
			{
				m_state = m_stateRequest;
				m_stateRequest = null;
				m_state.Func("enter", deltaTime);
			}
			
			m_state.Func("update", deltaTime);
			
			if (this.m_stateRequest)
			{
				this.m_state.Func("exit", deltaTime);
				this.m_state = null;
			}
			
			return this.m_stateRequest;
		}
		
		public function ChangeState(state:String) : void
		{
			if (this.m_state != null && this.m_state.Name == state)
			{
				return;
			}
			
			this.m_stateRequest = this.m_states[state];
		}
		
		public function PushState(name:String) : void
		{
			if (this.m_state.Name != name)
			{
				this.m_stateStack.push(this.m_state);
				ChangeState(name);
			}
		}
		
		public function Push2States(param1:String, param2:String) : void
		{
			if (this.m_state.Name != param1)
			{
				this.m_stateStack.push(this.m_state);
				this.m_stateStack.push(this.m_states[param1]);
				this.ChangeState(param2);
			}
		}
		
		public function PushStates(states:Array) : void
		{
			var i:int = 0;
			if (states.length > 0)
			{
				i = 0;
				while (i < states.length)
				{
					
					this.m_stateStack.push(this.m_states[states[i]]);
					i++;
				}
				this.ChangeState(states[(states.length - 1)]);
			}
		}
		
		public function PopState() : void
		{
			if (this.m_stateStack.length == 0)
			{
	
			}
			var state:RxState = this.m_stateStack.pop();
			while (state.Disposable == 1)
			{
				
				state = this.m_stateStack.pop();
			}
			
			this.ChangeState(state.Name);
		}
		
		public function PopAllStates() : void
		{
			var state:RxState = null;
			while (this.m_stateStack.length != 0)
			{
				
				state = this.m_stateStack.pop();
			}
			
			if (state != null)
			{
				this.ChangeState(state.Name);
			}
		}
		
		public function get CurrentState() : RxState
		{
			return this.m_state;
		}
	}
}